package safrain.nodelet.structure;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 这个类缓存一个类型内的属性信息，按照annotation的类型做分组存放
 * 
 * @author safrain
 * 
 */
public class Structure {
	/**
	 * 缓存的哪个类型
	 */
	public Class<?> type;

	public boolean autoRegister = true;

	/**
	 * 按照annotation分组存放属性信息
	 */
	private final Map<Class<? extends Annotation>, List<FieldInfo>> fieldMap = new HashMap<Class<? extends Annotation>, List<FieldInfo>>();

	public Structure(Class<?> type) {
		this.type = type;
	}

	public List<FieldInfo> getFieldInfoList(
			Class<? extends Annotation> annotationType) {
		List<FieldInfo> fieldInfoList = fieldMap.get(annotationType);
		if (fieldInfoList == null) {
			if (autoRegister) {
				fieldInfoList = register(annotationType);
			} else {
				throw new RuntimeException("Annotation "
						+ annotationType.getName() + " not registered");
			}
		}
		return fieldInfoList;
	}

	/**
	 * 注册某种annotation，添加这个分组
	 */
	public List<FieldInfo> register(Class<? extends Annotation> annotationType) {
		// 没有的话就添加
		List<FieldInfo> fieldInfoList = fieldMap.get(annotationType);
		if (fieldInfoList == null) {
			fieldInfoList = new ArrayList<FieldInfo>();
			fieldMap.put(annotationType, fieldInfoList);
		}

		fieldInfoList.clear();
		Class<?> currentType = type;
		// 取各个属性的反射信息，包括所有父类的
		// TODO：以后可以换getter/setter
		while (currentType != null) {
			for (Field field : currentType.getDeclaredFields()) {
				Annotation fieldAnnotation = field
						.getAnnotation(annotationType);
				if (fieldAnnotation != null) {
					FieldInfo fieldInfo = new FieldInfo();
					fieldInfo.annotation = fieldAnnotation;
					fieldInfo.field = field;
					fieldInfo.fieldName = field.getName();
					fieldInfo.fieldType = FieldType.getFieldType(field);
					fieldInfoList.add(fieldInfo);
				}
			}
			currentType = currentType.getSuperclass();
		}
		return fieldInfoList;
	}

}
